"""
增强版空调负荷预测系统完整演示
展示从数据处理到实时预测的完整流程
"""

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime
import os
import warnings
warnings.filterwarnings('ignore')

# 导入自定义模块
from enhanced_hvac_preprocessing import EnhancedHVACDataProcessor, load_enhanced_sample_data
from enhanced_hvac_transformer import EnhancedHVACConfig, create_enhanced_hvac_model
from enhanced_hvac_training import EnhancedHVACTrainer, load_enhanced_deployment_model


def demonstrate_data_preprocessing():
    """演示数据预处理功能"""
    print("=" * 60)
    print("📊 数据预处理演示")
    print("=" * 60)
    
    # 加载示例数据
    load_data, env_data, timestamps = load_enhanced_sample_data()
    print(f"原始数据:")
    print(f"  负荷数据形状: {load_data.shape}")
    print(f"  环境数据形状: {env_data.shape}")
    print(f"  时间范围: {timestamps[0]} 到 {timestamps[-1]}")
    
    # 创建并拟合处理器
    processor = EnhancedHVACDataProcessor()
    processor.fit(load_data, env_data, timestamps)
    
    # 转换数据
    processed_data = processor.transform(load_data, env_data, timestamps)
    
    print(f"\n处理后特征:")
    for key, value in processed_data.items():
        if isinstance(value, np.ndarray):
            print(f"  {key}: {value.shape}")
    
    # 显示特征信息
    feature_info = processor.get_feature_info()
    print(f"\n特征详情:")
    for category, features in feature_info.items():
        print(f"  {category}: {features}")
    
    return processor, processed_data


def demonstrate_model_architecture():
    """演示模型架构"""
    print("\n" + "=" * 60)
    print("🏗️ 模型架构演示")
    print("=" * 60)
    
    # 创建模型配置
    config = EnhancedHVACConfig(
        d_model=256,
        n_heads=8,
        n_layers=6,
        seq_len=168,  # 一周历史数据
        pred_len=24,  # 预测24小时
        n_env_features=2,  # 温度、湿度
        dropout=0.1
    )
    
    print(f"模型配置:")
    print(f"  模型维度: {config.d_model}")
    print(f"  注意力头数: {config.n_heads}")
    print(f"  Transformer层数: {config.n_layers}")
    print(f"  输入序列长度: {config.seq_len} 小时")
    print(f"  预测长度: {config.pred_len} 小时")
    print(f"  环境特征数: {config.n_env_features}")
    
    # 创建模型
    model, predictor, _ = create_enhanced_hvac_model()
    
    total_params = sum(p.numel() for p in model.parameters())
    trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
    
    print(f"\n模型统计:")
    print(f"  总参数数量: {total_params:,}")
    print(f"  可训练参数: {trainable_params:,}")
    print(f"  模型大小: ~{total_params * 4 / 1024 / 1024:.1f} MB")
    
    return config


def demonstrate_training_process():
    """演示训练过程"""
    print("\n" + "=" * 60)
    print("🚀 模型训练演示")
    print("=" * 60)
    
    # 数据准备
    load_data, env_data, timestamps = load_enhanced_sample_data()
    processor = EnhancedHVACDataProcessor()
    processor.fit(load_data, env_data, timestamps)
    processed_data = processor.transform(load_data, env_data, timestamps)
    
    # 创建序列
    X, y = processor.create_sequences(processed_data)
    
    print(f"训练数据准备:")
    print(f"  样本数量: {len(y)}")
    print(f"  输入序列长度: {X['load'].shape[1]}")
    print(f"  预测序列长度: {y.shape[1]}")
    
    # 创建模型和训练器
    config = EnhancedHVACConfig(
        d_model=128,  # 为演示降低模型复杂度
        n_heads=4,
        n_layers=3,
        seq_len=168,
        pred_len=24,
        n_env_features=2
    )
    
    trainer = EnhancedHVACTrainer(config)
    
    print(f"\n开始训练（演示版本，少量epochs）...")
    
    # 快速训练（演示用）
    training_result = trainer.train(
        X, y, 
        epochs=20,  # 演示用少量epochs
        batch_size=16, 
        learning_rate=0.001,
        patience=10
    )
    
    print(f"\n训练结果:")
    print(f"  最佳epoch: {training_result['best_epoch']}")
    print(f"  最佳验证损失: {training_result['best_val_loss']:.6f}")
    print(f"  最终验证MAE: {training_result['final_val_mae']:.6f}")
    
    # 评估模型
    evaluation_result = trainer.evaluate(X, y, processor)
    print(f"\n模型性能:")
    for metric, value in evaluation_result['overall_metrics'].items():
        print(f"  {metric}: {value:.4f}")
    
    # 创建部署包
    package_dir = trainer.create_deployment_package(processor)
    
    return package_dir


def demonstrate_real_time_prediction(package_dir: str):
    """演示实时预测功能"""
    print("\n" + "=" * 60)
    print("⚡ 实时预测演示")
    print("=" * 60)
    
    # 加载部署模型
    predictor, processor = load_enhanced_deployment_model(package_dir)
    
    print("部署模型加载成功！")
    
    # 模拟实时数据流
    print("\n模拟实时数据更新和预测...")
    current_time = datetime.datetime.now().replace(minute=0, second=0, microsecond=0)
    
    # 初始化历史数据（模拟一周的数据）
    for i in range(168):  # 一周的小时数
        time_point = current_time - datetime.timedelta(hours=168-i)
        
        # 模拟负荷值
        hour = time_point.hour
        base_load = 100 + 50 * np.sin(2 * np.pi * hour / 24 - np.pi/2)
        load_value = base_load + np.random.normal(0, 5)
        
        # 模拟环境数据
        temp = 20 + 10 * np.sin(2 * np.pi * time_point.timetuple().tm_yday / 365) + \
               3 * np.sin(2 * np.pi * hour / 24) + np.random.normal(0, 2)
        humidity = 60 + np.random.normal(0, 10)
        env_data = np.array([temp, humidity])
        
        predictor.update_data(load_value, env_data, time_point)
    
    # 进行预测
    print(f"\n当前时间: {current_time}")
    predictions, stats = predictor.predict_remaining_day()
    
    print(f"\n今日剩余时间预测结果:")
    print(f"  剩余小时数: {stats['remaining_hours']}")
    print(f"  平均负荷: {stats['mean_load']:.2f} kW")
    print(f"  峰值负荷: {stats['max_load']:.2f} kW")
    print(f"  最低负荷: {stats['min_load']:.2f} kW")
    if stats['peak_hour']:
        print(f"  峰值时间: {stats['peak_hour'].strftime('%H:%M')}")
    print(f"  预计总耗电量: {stats['total_consumption']:.2f} kWh")
    
    # 可视化预测结果
    visualize_predictions(predictions, stats, current_time)
    
    return predictions, stats


def visualize_predictions(predictions: np.ndarray, stats: dict, current_time: datetime.datetime):
    """可视化预测结果"""
    print("\n绘制预测曲线...")
    
    # 生成时间轴
    time_stamps = [current_time + datetime.timedelta(hours=i+1) 
                  for i in range(len(predictions))]
    
    plt.figure(figsize=(12, 6))
    
    # 绘制预测曲线
    plt.plot(time_stamps, predictions, 'b-', linewidth=2, label='预测负荷')
    plt.axhline(y=stats['mean_load'], color='r', linestyle='--', alpha=0.7, label=f"平均值: {stats['mean_load']:.1f} kW")
    
    # 标记峰值点
    if stats['peak_hour'] and len(predictions) > 0:
        peak_idx = np.argmax(predictions)
        plt.plot(time_stamps[peak_idx], predictions[peak_idx], 'ro', markersize=8, label=f"峰值: {stats['max_load']:.1f} kW")
    
    plt.title('今日剩余时间空调负荷预测', fontsize=14, fontweight='bold')
    plt.xlabel('时间')
    plt.ylabel('负荷 (kW)')
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.xticks(rotation=45)
    plt.tight_layout()
    
    # 保存图片
    plt.savefig('enhanced_hvac_prediction.png', dpi=300, bbox_inches='tight')
    plt.show()
    
    print("预测曲线已保存为 'enhanced_hvac_prediction.png'")


def demonstrate_feature_analysis():
    """演示特征分析"""
    print("\n" + "=" * 60)
    print("🔍 特征分析演示")
    print("=" * 60)
    
    # 生成数据
    load_data, env_data, timestamps = load_enhanced_sample_data()
    processor = EnhancedHVACDataProcessor()
    processed_data = processor.transform(load_data, env_data, timestamps)
    
    # 分析时间特征分布
    print("时间特征分布分析:")
    
    # 小时分布
    hours = processed_data['hour']
    hour_counts = np.bincount(hours, minlength=24)
    peak_hours = np.argsort(hour_counts)[-3:]  # 前3个最频繁的小时
    print(f"  最活跃时段: {peak_hours} 时")
    
    # 星期分布
    weekdays = processed_data['dayofweek']
    weekday_names = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
    for i, name in enumerate(weekday_names):
        count = np.sum(weekdays == i)
        print(f"  {name}: {count} 个时间点")
    
    # 节假日统计
    holidays = processed_data['is_holiday']
    holiday_ratio = np.mean(holidays) * 100
    print(f"  节假日比例: {holiday_ratio:.1f}%")
    
    # 环境特征统计
    print(f"\n环境特征统计:")
    temp_data = env_data[:, 0]
    humidity_data = env_data[:, 1]
    print(f"  温度范围: {np.min(temp_data):.1f}°C - {np.max(temp_data):.1f}°C (平均: {np.mean(temp_data):.1f}°C)")
    print(f"  湿度范围: {np.min(humidity_data):.1f}% - {np.max(humidity_data):.1f}% (平均: {np.mean(humidity_data):.1f}%)")


def main():
    """主演示函数"""
    print("🏢 增强版空调负荷预测系统演示")
    print("基于Transformer的多特征时间序列预测")
    print("包含查表嵌入、周期性编码和实时预测功能")
    
    try:
        # 1. 数据预处理演示
        processor, processed_data = demonstrate_data_preprocessing()
        
        # 2. 模型架构演示
        config = demonstrate_model_architecture()
        
        # 3. 特征分析演示
        demonstrate_feature_analysis()
        
        # 4. 训练演示（可选，时间较长）
        user_input = input("\n是否运行训练演示？(可能需要几分钟) [y/N]: ")
        if user_input.lower() in ['y', 'yes']:
            package_dir = demonstrate_training_process()
            
            # 5. 实时预测演示
            demonstrate_real_time_prediction(package_dir)
        else:
            print("\n跳过训练演示。")
            print("注意: 要运行实时预测演示，需要先完成模型训练。")
        
        print("\n" + "=" * 60)
        print("✅ 演示完成！")
        print("=" * 60)
        print("\n主要特点总结:")
        print("✓ 增强的数据预处理（异常值处理、特征工程）")
        print("✓ 基于查表嵌入的时间特征处理")
        print("✓ 周期性时间编码（正弦余弦）")
        print("✓ 多头注意力机制的Transformer架构")
        print("✓ 实时数据更新和增量预测")
        print("✓ 完整的训练和部署流程")
        
    except Exception as e:
        print(f"\n❌ 演示过程中发生错误: {e}")
        print("请检查依赖库是否正确安装。")


if __name__ == "__main__":
    main()
